//: Playground - noun: a place where people can play

import UIKit

/**
 Swift 3.0 开始,定义枚举值,统一小写
 */

enum CompassPoint {

    case north
    case south
    case east
    case west
}

enum CompassPoint1 {

    case north, south, ease, west
}

enum Rank: Int{ // Int 设置枚举值的类型
    // 定义枚举值设置值
    case ace
    // 可以case 后面一次定义多个枚举值
    case two, three, four, five, six, seven, eight, nine, ten
    case jack, queen, king
    
    // 定义函数 如果多人合作的时候,可以使用这个让别人更加了解你定义的属性的含义
    func simpleDescription() -> String {
        switch self { // self 就是这个枚举本身
        case .ace:
            return "ace1"
        case .jack:
            return "jack1"
        case .queen:
            return "queen1"
        case .king:
            return "king1"
        default:
            return String(self.rawValue)
        }
    }
}

let ace = Rank.king
ace.rawValue
ace.simpleDescription()

let rank = Rank(rawValue: 0)

enum CompassPoint2:Character {

    case north = "1"
    case south = "2"
    case east = "3"
    case west = "5"
}

CompassPoint2.west.rawValue

/**
 1.如果你没有定义枚举的原始值类型,你不能通过上述方法获取原始值
 2.输入定义的是数字类型 ，原始值对应的是数字本身，
 3.如果定义的是字符串类型,但你没有給它赋值,这个时候,你获取的原始值就是你定义的名字
 */

// 提供值创建枚举

enum ServerResponse {

    case result(String, String)
    case failure(String)
}

let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("out of chinese")

/**
 这个方式定义的枚举 不能使用 == 来做判断处理,我们应该使用模式匹配的方式处理,这种定义方式强调的是传值,如下
 */

switch success {
case let .result(sunrise, sunset):
    
    print("sunrise is at \\(sunrise) and sunset is at \\(sunset)");
case let .failure(message):
    print("Failure...  \\(message)")
}


// 或者
switch success {
case  .result(let sunrise, let sunset): // 模式匹配
    print("Sunrise is at \\(sunrise) and sunset is at \\(sunset).")
case  .failure(let message):
    print("Failure...  \\(message)")
}

// indirect 使用方法 如果你定义的枚举是递归的形式,必须有关键字indirect 修饰,不然系统会编译报错

enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

ArithmeticExpression.number(3)


let expression =  ArithmeticExpression.addition(ArithmeticExpression.number(3), ArithmeticExpression.number(4))

indirect enum ArithmeticExpression1 {
    case number(Int)
    case addition(ArithmeticExpression1, ArithmeticExpression1)
    case multiplication(ArithmeticExpression1, ArithmeticExpression1)
}

let expression1 =  ArithmeticExpression1.addition(ArithmeticExpression1.number(3), ArithmeticExpression1.number(4))

// 重新实现SWIFT标准库的可选类型(使用泛型技术)

enum OptionalValue<wrapped> {

    case none
    case some(wrapped)
}

var possibleInteger: OptionalValue<Int> = .none
possibleInteger = .some(100)

protocol Skill {

    mutating func modifyMusic(name: String)
}

enum Type: String, Skill {

    case name = "123"
    mutating internal func modifyMusic(name: String) {
        
        self = Type(rawValue: "123")!
    }
}

// 枚举不能包含存储属性,但是可以包含静态变量和计算属性

enum SomeEnumeration:Int {

    case one = 2
    case two = 345
    // 静态变量
    static var storeTypeProperty = "Some value"
    // 静态计算属性
    static var computedTypeProperty: Int {
    
        return 6;
    }
    
    // 计算属性
    var getRaw: Int {
    
        return self.rawValue
    }
}

enum Locale {

    case none
    case base
    case language(String)
    
    var isChinese:Bool {
    
        if case .language("chinese") = self {
            
            return true
        }
        
        return false
    }
    
    // 是否是其他语言
    var isLanguage:Bool{
        if case .language = self {
            return true
        }
        return false
    }
    
    var isBase: Bool {
        if case .base = self {
            return true
        }
        
        return false
    }
    
    var isNone: Bool {
        if case .none = self {
            return true
        }
        return false
    }
}

//let locale = Locale.language("english")
//
//switch locale {
//case Locale.base: print(locale)
//case Locale.none: print(locale)
//case Locale.language("english"): print(locale)
//case Locale.language(let x): print(x)
//    
//}

let locale = Locale.language("chinese")
print(locale.isChinese)




